package com.vagavaga.tcpt;

/**
 * Utility class for working with hex values. This class has methods for
 * converting binary array to strings represented in hex, and also for decoding
 * hex coded strings to binary arrays.
 * 
 * @author <code>River</code>
 * @version <code>1.0</code>
 */

final class HexEncoder {

    private HexEncoder() {
        // no instantiation.
    }

    /**
     * Hex encodes every byte in passed byte array, and returns resulting
     * string.
     * 
     * @param b
     *        byte array to encode.
     * @return hex encoded string.
     */
    public static String encode(byte[] b) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            sb.append(byteToHex(b[i]));
        }
        return sb.toString();
    }

    /**
     * Returns hex representation of passed byte value. Difference with this and
     * {@link Integer#toHexString(int)} is that this method will always return
     * string whose length is 2.
     * 
     * @param b
     *        byte witch value we want in hex.
     * @return 2 characters long string containing hex representation of value.
     */
    public static String byteToHex(byte b) {
        StringBuffer sb = new StringBuffer();
        int i = b < 0 ? b & 0xff : b;
        if (i < 16) {
            sb.append('0');
        }
        sb.append(Integer.toHexString(i));
        return sb.toString();
    }

    /**
     * Decodes hex encoded string.
     * 
     * @param s
     *        hex encoded string.
     * @return byte array representing data in string.
     */
    public static byte[] decode(String s) {
        int pos = 0;
        int len = s.length();
        byte[] b = new byte[len / 2];

        while (pos < len) {
            String hex = s.substring(pos, pos + 2);
            b[pos >>> 1] = (byte) Integer.parseInt(hex, 16);
            pos += 2;
        }

        return b;
    }
}
